﻿using Kimd.Common;
using Kimd.Logic;
using Kimd.Machine;
using Kimd.Motion;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WorkStation.Common;

namespace WorkStation.Logic
{
    /// <summary>
    /// 缓存流线
    /// </summary>
    public class BufferConveyorLogic : FlowBase
    {
        private Axis _conveyor;
        private Cylinder _stationNeedInPlate;
        private Cylinder _stationInPlateFinish;
        private Sensor _bufferPlateInPosition;
        private Sensor _frontStationOutRequest;
        private Sensor _frontStationOutPlateNow;
        public BufferConveyorLogic(string flowName, FlowManager flowmanager) 
            : base(flowName, flowmanager)
        {
            _conveyor = MachineResource.Instance.MachineAxis["缓存流线步进"];
            _stationNeedInPlate = MachineResource.Instance.MachineCylinder["本站允许入料"];
            _stationInPlateFinish = MachineResource.Instance.MachineCylinder["本站入料完成"];
            _bufferPlateInPosition = MachineResource.Instance.MachineSensor["缓存到位光电"];
            _frontStationOutRequest = MachineResource.Instance.MachineSensor["上站出料请求"];
            _frontStationOutPlateNow = MachineResource.Instance.MachineSensor["上站出料中"];

            RegisterDirectSignal("缓存板到位");
        }

        public override void Calibrate()
        {
            base.Calibrate();
        }

        public override void Home()
        {
            if(_conveyor.ServoWarn)
                _conveyor.ClearAlarm();
            Thread.Sleep(200);
            if(!_conveyor.ServoOn)
                _conveyor.SetServoOn();
            Thread.Sleep(200);
            _conveyor.Stop(false);
            //复位信号
            _stationNeedInPlate.Off();
            _stationInPlateFinish.Off();
            //检查是否有料盘
            checkProductStatus();

            _conveyor.Zero();
        }

        public override void Init(out string errInfo)
        {
            base.Init(out errInfo);
        }

        public override void InSingleRunMode()
        {
            base.InSingleRunMode();
        }

        public override void Method()
        {
            if (!CheckFlowCondition()) return;
            //向前站要料
            _stationNeedInPlate.On();
            if (!GlobalVariable.IsDryRun)
            {
                //等待前站出料信号
                while (!_frontStationOutPlateNow.WaitOn() && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
            }
            else
            {
                while (!GlobalVariable.FrontAllowPlateOut && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
            }
            //关掉要料信号
            _stationNeedInPlate.Off();
            //轨道开转
            SingleAxisMoveContinuous(_conveyor, true);
            //等待盘子到位
            WaitSensor(_bufferPlateInPosition, 10000, "缓存流线等待板到位超时!请检查是否卡料", 
                       () => { _conveyor.Stop(false); }, 
                       () => { SingleAxisMoveContinuous(_conveyor, true); });
            //到板后延时
            Thread.Sleep(100);
            _conveyor.Stop(false);
            if (!CheckFlowCondition()) return;
            SetSignal("缓存板到位");
            WaitForSignal("贴合轨道", "要板");
            if (!CheckFlowCondition()) return;
            retry:
            //向贴合流道送板
            SingleAxisMoveContinuous(_conveyor, true);
            //等待板子流出去
            DateTime startTime = DateTime.Now;
            TimeSpan ts = DateTime.Now - startTime;
            while(_bufferPlateInPosition.WaitOn() && !IsBreak() && ts.TotalMilliseconds < 5000)
            {
                ts = DateTime.Now - startTime;
                Thread.Sleep(20);
            }
            if(ts.TotalMilliseconds >= 5000)
            {
                _conveyor.Stop(false);
                ShowWarnAndPause("缓存流线等待板子流出超时!", _conveyor.Module);
                if (!CheckFlowCondition()) return;
                goto retry;
            }
            Thread.Sleep(1000);
            if (!CheckFlowCondition()) return;
            _conveyor.Stop(false);
            if (!CheckFlowCondition()) return;
            Thread.Sleep(1000);
        }

        public override void OnStop()
        {
            base.OnStop();
        }

        public override bool PreStartCheck()
        {
            return base.PreStartCheck();
        }

        public override void SpotCheck()
        {
            base.SpotCheck();
        }
        public void checkProductStatus()
        {
            while (_bufferPlateInPosition.WaitOn() && !IsBreak())
            {
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.InfoAndPause, $"缓存流道上有料盘，请取走", this.Description, 0, "系统"));
                //出错，停下所有线程
                _flowManager.Pause();
                //若为报错，需重新检测启动信号
                WaitForStart();
                if (!CheckFlowCondition()) return;

                Thread.Sleep(20);
            }
        }
    }
}
